﻿
/*
Service: 适用于管理所有服务器端的Rest接口的静态对象
serviceList: 包含了Rest接口的地址，方法，名称
InitService: 该方法会为每一个serviceItem生成4个方法
example:
Item: { name: "GetCurrentUser", url: "/core/GetCurrentUser", method: "get" },
Method: 
异步调用
GetCurrentUser
同步调用
GetCurrentUser_Sync
异步调用，使用缓存
GetCurrentUser_Cache
同步调用，使用缓存
GetCurrentUser_CacheSync

memo: 带缓存的方法只有当Rest的Method是Get的时候才能发生
*/

var EzDesk = $.extend(EzDesk, {});
EzDesk.Service = GetService();
EzDesk.Service.BuildReference = GetBuildReferenceMethod();



function GetService() {
    var Service = {};
    Service.Cache = {};
    Service.serviceList = [
        { name: "GetCurrentUser", url: "/core/GetCurrentUser", method: "get" },
        { name: "GetAllUserInfo", url: "/core/GetAllUserInfo", method: "get" },
        { name: "GetCurrentDate", url: "/Core/GetCurrentDate", method: "get" },
        { name: "GetCurrentDate", url: "/Core/GetCurrentTime", method: "get" },
        { name: "GetUserInfoInDept", url: "/core/GetUserInfoInDept", method: "get" },
        { name: "HasPermission", url: "/Core/HasPermission", method: "post" },
        
        { name: "DoCheckUserExist", url: "/Staff/DoCheckUserExist", method: "post" },

        { name: "PersonalAttendanceListPerMonth", url: "/attendance/PersonalAttendanceListPerMonth", method: "get" },

        { name: "GetProjectListForUser", url: "/project/GetProjectListForUser", method: "get" },
        { name: "GetAllProjects", url: "/project/GetAllProjects", method: "get" },
        { name: "GetWorkItemStatuses", url: "/project/GetWorkItemStatuses", method: "get" },
        { name: "GetFullProjectById", url: "/project/GetFullProjectById", method: "get" },
        { name: "GetTasksInProject", url: "/project/GetTasksInProject", method: "get" },
        { name: "GetProjectTemplateList", url: "/project/GetProjectTemplateList", method: "get" },
        { name: "CreateProjectTemplate", url: "/project/CreateProjectTemplate", method: "post" },
        { name: "RemoveProjectTemplate", url: "/project/RemoveProjectTemplate", method: "post" },

        { name: "ChangeProjectStartOn", url: "/project/ChangeProjectStartOn", method: "post" },
        { name: "DoUpdateProjectBasicInfo", url: "/project/DoUpdateProjectBasicInfo", method: "post" },

        { name: "GetTasks", url: "/project/GetTasksInProject", method: "get" },
        { name: "GetWorkitemsInTask", url: "/project/GetWorkitemsInTask", method: "get" },
        { name: "AddNewTask", url: "/project/AddNewTask", method: "post" },
        { name: "UpdateTask", url: "/project/UpdateTask", method: "post" },
        { name: "DeleteTask", url: "/project/DeleteTask", method: "post" },
        { name: "AcceptWorkitem", url: "/project/AcceptWorkitem", method: "post" },
        { name: "DoFinishWorkitem", url: "/project/DoFinishWorkitem", method: "post" },
        { name: "DoConfirmWorkitem", url: "/project/DoConfirmWorkitem", method: "post" },
        { name: "DoExtendWorkitem", url: "/project/DoExtendWorkitem", method: "post" },
        { name: "DoTakeOwnershipWorkitem", url: "/project/DoTakeOwnershipWorkitem", method: "post" },
        { name: "GetWorkItems", url: "/project/GetWorkItems", method: "get" },
        { name: "OwnDailyFinishedWorkitems", url: "/project/OwnDailyFinishedWorkitems", method: "get" },
        { name: "DoUpdateDailyWork", url: "/project/DoUpdateDailyWork", method: "post" },
        { name: "WorkitemStatistics", url: "/project/WorkitemStatistics", method: "get" },
    ];


    Service.InitService = function () {
        function GetCacheKey(serviceItem, args) {
            var argStr = args ? $.toJSON(args) : "";
            return serviceItem.name + argStr;
        }
        function GenerateSyncMethod(serviceItem) {
            return function (callback, args, message, beforeCallBack, afterCallBack) {
                $.AjaxBusy.show(message);
                var returnResult;
                var cacheKey = GetCacheKey(serviceItem, args);
                $.SyncMethod(serviceItem.url, serviceItem.method)(function (result) {
                    EzDesk.Service.BuildReference(result);
                    Service.Cache[cacheKey] = result;
                    returnResult = result;
                }, args, beforeCallBack, afterCallBack);

                $.AjaxBusy.hide();

                if (callback && callback != null)
                    callback(returnResult);
                return returnResult;
            }
        }
        function GenerateAsyncMethod(serviceItem) {
            return function (callback, args, beforeCallBack, afterCallBack) {
                var cacheKey = GetCacheKey(serviceItem, args);
                $.AsyncMethod(serviceItem.url, serviceItem.method)(function (result) {
                    EzDesk.Service.BuildReference(result);
                    Service.Cache[cacheKey] = result;
                    callback(result);
                }, args, beforeCallBack, afterCallBack);
            }
        }
        function GenerateCacheSyncMethod(serviceItem) {
            return function (callback, args, message, beforeCallBack, afterCallBack) {
                var cacheKey = GetCacheKey(serviceItem, args);
                if (!Service.Cache[cacheKey] || Service.Cache[cacheKey] == null) {
                    Service[serviceItem.name + "_Sync"](function (result) { }, args, message, beforeCallBack, afterCallBack);
                }
                if (callback && callback != null) callback(Service.Cache[cacheKey]);
                return Service.Cache[cacheKey];
            }
        }
        function GenerateCacheMethod(serviceItem) {
            return function (callback, args, beforeCallBack, afterCallBack) {
                var cacheKey = GetCacheKey(serviceItem, args);
                if (!Service.Cache[cacheKey] || Service.Cache[cacheKey] == null) {
                    Service[serviceItem.name](function (result) {
                        callback(result);
                    }, args, beforeCallBack, afterCallBack);
                }
                else
                    callback(Service.Cache[cacheKey]);
            }
        }

        for (var i = 0; i < Service.serviceList.length; i++) {
            var item = Service.serviceList[i];
            Service[item.name + "_Sync"] = GenerateSyncMethod(item);
            Service[item.name] = GenerateAsyncMethod(item);
            if (item.method == "get") {
                Service[item.name + "_CacheSync"] = GenerateCacheSyncMethod(item);
                Service[item.name + "_Cache"] = GenerateCacheMethod(item);

            }
        }
    };

    Service.InitService();
    return Service;
};

function GetBuildReferenceMethod() {
    var dictionary = {};
    var buildReference = function () { };
    buildReference = function (obj) {
        if (typeof (obj) != 'object') return;

        if (obj['$id']) {
            dictionary[obj['$id']] = obj;
        }
        for (var p in obj) {
            if (typeof (obj[p]) == 'object' && obj[p] != null) {
                if (obj[p]['$ref']) {
                    var refId = obj[p]['$ref'];
                    obj[p] = dictionary[refId];
                }
                else
                    buildReference(obj[p]);
            }
        }
        return obj;
    }
    return buildReference;
}
